
#ifndef SX_GRID_AXIS_CONTROLLER_H
#define SX_GRID_AXIS_CONTROLLER_H

#include <sxSceneController.h>
#include <sxPlotAxes_Archetype.h>

#include <sxCuboid_Archetype.h>

/* Camera Abstract-Renderer Representation */
using Sx::Graphics::Objects::Rendering::RendererImplementation;
using Sx::Graphics::Archetypes::Objects::PlotAxes_Archetype;
using Sx::Graphics::Archetypes::Objects::Cuboid_Archetype;

namespace Sx {
namespace Interface {

class Canvas;

/*
 * The PlotController class provides the ability to navigate a 2D Cartesian
 * plot with a 3D orthographic camera. The axis that are displayed simply
 * depends on which AxisPlane is provided (XY, YZ, XZ). The camera provides the
 * ability to navigate the entire plot (allows for panning and zooming).
 *
 * This plot controller contains a PlotAxes_Archetype. This provides a 
 * fixed-length Cartesian plane with line-ticks, a grid, and line numbers.
 */
class PlotController : public SceneController {
public:
	PlotController(Viewport* viewport,
		const std::shared_ptr<Canvas>& canvas, 
		const std::shared_ptr<ScenePickingController>& pickingController, 
		const std::shared_ptr<RendererImplementation>& cameraRenderer, 
		const std::shared_ptr<RendererImplementation>& plotRenderer);

	PlotController(Viewport* viewport,
		const std::shared_ptr<Canvas>& canvas, 
		const std::shared_ptr<ScenePickingController>& pickingController, 
		const std::shared_ptr<RendererImplementation>& cameraRenderer, 
		const std::shared_ptr<RendererImplementation>& plotRenderer,
		unsigned int nxTicks, 
		unsigned int pxTicks,
		unsigned int nyTicks,
		unsigned int pyTicks,
		unsigned int nzTicks,
		unsigned int pzTicks,
		float spacing);

	virtual ~PlotController();

	/* Viewport Interface Overriding */
	virtual bool initialize();
	virtual void render() const;

	bool setDisplayX(bool b);
	bool setDisplayY(bool b);
	bool setDisplayZ(bool b);

	bool setDisplayTicks(bool b);
	bool setDisplayTickLabels(bool b);
	bool setDisplayGrid(bool b);
	bool setDisplayGrid(Math::AxisPlane plane, bool b);

	bool setXTicks(unsigned int ticks, bool positive);
	bool setYTicks(unsigned int ticks, bool positive);
	bool setZTicks(unsigned int ticks, bool positive);
	bool setGridTicks(unsigned int nxTicks, unsigned int pxTicks, unsigned int nyTicks, unsigned int pyTicks, unsigned int nzTicks, unsigned int pzTicks);

	bool setLabelInterval(unsigned int interval);

	virtual void mousePressEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	virtual void mouseReleaseEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	virtual void mouseClickEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	virtual void mouseMoveEvent(int x, int y, MouseButton button, ModifierKey modifierKey);
	virtual void mouseWheelEvent(int delta);

protected:
	std::shared_ptr<PlotAxes_Archetype> plot;
};

}

}

#endif
